package com.gyy.jLibModbus;

import com.intelligt.modbus.jlibmodbus.Modbus;
import com.intelligt.modbus.jlibmodbus.master.ModbusMaster;
import com.intelligt.modbus.jlibmodbus.master.ModbusMasterFactory;
import com.intelligt.modbus.jlibmodbus.tcp.TcpParameters;

import java.net.InetAddress;


/**
 * @Author gmd
 * @Description modbus通讯，使用jlibmodbus框架写入slave数据
 * @Date 2021-12-23 14:07:12
 */
public class JLibModbusWrite {

    public static ModbusMaster master;

    /**
     * 初始化连接modbus Master主机
     */
    public static void initConnect() throws Exception {
        // 设置主机TCP参数
        TcpParameters tcpParameters = new TcpParameters();
        // 设置TCP的ip地址
        InetAddress address = InetAddress.getByName("127.0.0.1");

        /**
         * 如果是本机localhost的话，可以直接使用
         * tcpParameters.setHost(InetAddress.getLocalHost());
         */

        // TCP参数设置ip地址
        tcpParameters.setHost(address);
        // TCP设置长连接
        tcpParameters.setKeepAlive(true);
        // TCP设置端口，这里设置是默认端口502
        tcpParameters.setPort(Modbus.TCP_PORT);

        // 创建一个主机
        master = ModbusMasterFactory.createModbusMasterTCP(tcpParameters);
        // 设置事务ID自动递增
        Modbus.setAutoIncrementTransactionId(true);

        if (!master.isConnected()) {
            // 开启连接
            master.connect();
        }
    }


    /**
     * 关闭连接
     */
    public static void closeConnect() throws Exception {
        master.disconnect();
    }


    /**
     * 批量写入Coil线圈（0x01）布尔数据
     *
     * @param slaveId 从机ID
     * @param offset  开始地址
     * @param values  写入数据
     */
    public static void writeCoils(int slaveId, int offset, boolean[] values) throws Exception {
        master.writeMultipleCoils(slaveId, offset, values);
        System.out.println("\nCoil线圈（0x01）布尔数据写入如下：");
        for (boolean value : values) {
            System.out.println("Address: " + offset++ + ", Value: " + value);
        }
    }


    /**
     * 批量写入Discrete离散量输入（0x02）布尔数据
     *
     * @param slaveId 从机ID
     * @param offset  开始地址
     * @param values  写入数据
     */
    public static void writeDiscrete(int slaveId, int offset, boolean[] values) {
        System.out.println("\n不允许修改Discrete（0x03）状态数据！");
    }

    /**
     * 批量写入HoldingRegisters寄存器（0x03）数据
     *
     * @param slaveId 从机ID
     * @param offset  开始地址
     * @param values  写入数据
     */
    public static void writeHoldingRegisters(int slaveId, int offset, int[] values) throws Exception {
        master.writeMultipleRegisters(slaveId, offset, values);

        System.out.println("\nHoldingRegisters寄存器（0x03）数据数据写入如下：");
        for (int value : values) {
            System.out.println("Address: " + offset++ + ", Value: " + value);
        }
    }


    /**
     * 批量写入InputRegister寄存器（0x04）数据
     *
     * @param slaveId 从机ID
     * @param offset  开始地址
     * @param values  写入数据
     */
    public static void writeInputRegisters(int slaveId, int offset, int[] values) throws Exception {
        System.out.println("\n不允许修改InputRegister（0x04）状态数据！");
    }


    public static void main(String[] args) throws Exception {
        initConnect();

        writeCoils(1, 0, new boolean[]{true, true, true, true, false, true});

        writeDiscrete(2, 0, new boolean[]{true, true, true, true, false, true});

        writeHoldingRegisters(3, 0, new int[]{1, 2, 3, 4, 5, 6, 7, 8});

        writeInputRegisters(4, 0, new int[]{1, 2, 3, 4, 5, 6, 7, 8});

        closeConnect();
    }

}
